import copy
import pickle
from decimal import Decimal

from django.shortcuts import render

# Create your views here.
from django.utils import timezone
from redis import StrictRedis
from rest_framework.pagination import PageNumberPagination
from rest_framework.viewsets import ModelViewSet
from orders.sers import OrderGoodsSerializer,OrderInfoSerializer
from rest_framework.response import Response
from rest_framework.views import APIView

from goods.models import SKU
from orders.models import OrderInfo, OrderGoods
from users.models import Address


class OrderGoodsViewSet(APIView):
    def get(self, request):
        # 获取确认订单中的商品数据,  =>  购物车中的选中的商品
        # 1. 获取用户,
        # 2. 获取redis 购物车
        # 3. 取出购物车中的选中的商品
        # 4. 返回商品信息

        # 1. 获取用户id
        user = request.user

        # 2. 获取redis中的购物车数据
        redis_client = StrictRedis()
        redis_carts = redis_client.get(str(user.id) + '_carts')
        if redis_carts:
            carts = pickle.loads(redis_carts)
        else:
            carts = {}
            return Response({'msg': '购物车为空'})
        # 3. 返回购物车中的内容给前端,
        # [{sku_img:xxxx, sku_id:xxxx,  sku_name:xxxx, sku_price:xx , count:12, selected:True},{}]
        # 1:{count:1, selected: True},
        sku_list = []
        for sku_id, count_selected in carts.items():
            if count_selected.get('selected'):
                sku = SKU.objects.get(id=sku_id)
                sku_data = {
                    'id': sku.id,
                    'name': sku.name,
                    'price': sku.price,
                    'count': count_selected['count'],
                    'default_image_url': sku.default_image_url.url
                    # default_image_url是路径, 没有前缀,  default_image_url.url(), 是完整路径, 前端需要完整路径
                }
                sku_list.append(sku_data)
        return Response({'code': 0, 'msg': '购物车获取成功', 'data': sku_list})


# 提交订单, 保存订单基本信息和订单商品信息
class OrderCommitView(APIView):
    """提交订单"""

    def post(self, request):
        """保存订单信息和订单商品信息"""
        # 获取当前要保存的订单数据
        data = request.data
        address_id = data.get('address')  # 收货地址id
        pay_method = data.get('pay_method')  # 支付方式
        # 校验参数
        if not all([address_id, pay_method]):
            return Response({'code': '999', 'msg': '缺少必传参数'})
        # 判断address_id是否合法
        try:
            address = Address.objects.get(id=address_id)
        except Exception:
            return Response({'code': '999', 'msg': '参数address_id错误'})
        # 判断pay_method是否合法
        # if pay_method not in [OrderInfo.PAY_METHODS_ENUM['CASH'], OrderInfo.PAY_METHODS_ENUM['ALIPAY']]:
        if pay_method not in [1, 2]:
            return Response({'code': '999', 'msg': '参数pay_method错误'})
        # 获取登录用户
        user = request.user

        # 2. 获取redis中的购物车数据
        redis_client = StrictRedis()
        redis_carts = redis_client.get(str(user.id) + '_carts')
        if redis_carts:
            carts = pickle.loads(redis_carts)
        else:
            carts = {}
            return Response({'msg': '购物车为空'})

        # 生成订单编号：年月日时分秒+用户编号
        order_id = timezone.localtime().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)
        # 保存订单基本信息 OrderInfo（一）
        order = OrderInfo.objects.create(
            order_id=order_id,
            user=user,
            address=address,
            total_count=0,  # 创建订单的时候是0
            total_amount=Decimal('0'),  # 创建订单的时候是0
            freight=Decimal('10.00'),
            pay_method=pay_method,
            status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'] if pay_method == OrderInfo.PAY_METHODS_ENUM['ALIPAY'] else
            OrderInfo.ORDER_STATUS_ENUM['UNSEND']
        )

        # 从redis读取购物车中被勾选的商品信息

        # 3. 返回购物车中的内容给前端,
        # [{sku_img:xxxx, sku_id:xxxx,  sku_name:xxxx, sku_price:xx , count:12, selected:True},{}]
        # 1:{count:1, selected: True},
        sku_list = []  # 从redis读取购物车中被勾选的商品信息
        """
        [
        {'sku':sku, 'price':123.00, 'count':2},
        {'sku':sku, 'price':123.00, 'count':2},
        {'sku':sku, 'price':123.00, 'count':2}
        ]
        """
        for sku_id, count_selected in carts.items():
            if count_selected.get('selected'):
                sku = SKU.objects.get(id=sku_id)
                sku_data = {
                    'sku': sku,
                    'price': sku.price,
                    'count': count_selected['count'],
                    # default_image_url是路径, 没有前缀,  default_image_url.url(), 是完整路径, 前端需要完整路径
                }
                sku_list.append(sku_data)

        # 遍历购物车中被勾选的商品信息



        # 遍历购物车中被勾选的商品信息
        # [
        #     {'sku': sku, 'price': 123.00, 'count': 2},
        #     {'sku': sku, 'price': 123.00, 'count': 2},
        #     {'sku': sku, 'price': 123.00, 'count': 2}
        # ]
        for sku_data in sku_list:
            # 查询SKU信息
            sku = sku_data['sku']
            # 判断SKU库存
            sku_count = sku_data['count']  # 购物车中的数量
            if sku_count > sku.stock:
                return Response({'code': '999', 'msg': '库存不足'})

            # SKU减少库存，增加销量
            sku.stock -= sku_count  #减少库存
            sku.sales += sku_count  #增加销量
            sku.save()

            # 修改SPU销量
            sku.spu.sales += sku_count
            sku.spu.save()

            # 保存订单商品信息 OrderGoods（多）
            OrderGoods.objects.create(
                order=order,
                sku=sku,
                count=sku_count,
                price=sku.price,
            )

            # 保存商品订单中总价和总数量
            order.total_count += sku_count
            order.total_amount += (sku_count * sku.price)

        # 添加邮费和保存订单信息
        order.total_amount += order.freight
        order.save()

        # 清除购物车中已结算的商品
        """
        {
            1:{count:1, selected: True},
            2:{count:6, selected: True},
            3:{count:3, selected: True}
        },
        """
        bak_carts = copy.deepcopy(carts)
        for sku_id, count_selected in bak_carts.items():
            if count_selected.get('selected'):
                del carts[sku_id]

        carts_bytes = pickle.dumps(carts)

        redis_client.set(str(user.id) + '_carts', carts_bytes)

        # 响应提交订单结果
        return Response({'code': 0, 'msg': '下单成功', 'order_id': order.order_id})


class PageNum(PageNumberPagination):
    page_size_query_param = 'page_size'
    page_size = 5000


class OrderInfoModelViewSet(ModelViewSet):
    queryset = OrderInfo.objects.all()
    serializer_class = OrderInfoSerializer

    filter_fields = ('user',)

    pagination_class = PageNum